<?
if ( ! defined('APP-START')) exit('No direct script access allowed');

/**
 * @FILE		pasteboard_c.php
 * @DESC		main controller that does all the routing to TPL+VIEW or CONTROLLER
 * @PACKAGE		PASTEBOARD
 * @VERSION		1.0.0
 * @AUTHOR		James McCarthy
 * @EMAIL		james.mccarthy@gmail.com
 * @DATE		February 17, 2011

	Copyright (C) 2011  James McCarthy, http://sjamesmccarthy.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  
 */

class app
{
		public 	 $version = '0.1';
		
		public 	 $data = array();
		public   $class_reg = array();
		public   $auto_libs = array();
		
		/* Query_String associations; CHANGE AT OWN RISK */
		public	 $view_key = 'v';
		public	 $tpl_key = 't';
		public	 $ctrl_key = 'c';
		public	 $method_key = 'm';
		
		/* System Path Information; CHANGE AT OWN RISK */
		public	 $controller_path = 'controllers/'; 
	 	public	 $model_path	= 'models/';
		public	 $views_path = 'views/';
		public	 $snip_path = 'views/snips/';
		public	 $theme_path = 'views/themes/';
		public	 $meta_path = 'views/meta/';
		public	 $library_path = 'libraries/';
		public	 $jquery_path = '/libraries/third-party/jquery/';
		public	 $log_path = 'logs/';
		public	 $log_file_status = NULL;
		
		/* Config file variables */
		public 	 $key_google_analytics;
		public 	 $key_bing_ananlytics;
		public 	 $key_yahoo_analytics;
		public	 $use_recaptcha;
		public	 $key_recaptcha;
		public 	 $SITE_NAME;
		public 	 $CONTACT_EMAIL;
		public 	 $DEFAULT_VIEW;
		public 	 $DEFAULT_TPL;
		public 	 $DEFAULT_THEME;
		public 	 $DOC_ROOT;
		public 	 $USE_LOG;
		public 	 $USE_PROFILER;
		public	 $DB_NAME;
		public	 $DB_HOST;
		public	 $DB_USER;
		public	 $DB_PSWD;
		public	 $SITE_URL;

	public function __construct()
	{		
		/* init log file */
		$this->__init_config();		
		
		/* init log file */
		$this->__init_log();
				
		/* auto load any extra files */
		$this->__autoload_libs();
		
		/* Checks to see if browser is from Apple device */
		// $this->check_mobile_device();
		/* Commented this out until a better rework can be done */
		
		/* Checks for the current theme */
		$this->get_theme();
		
		/* Checks to see if the URI needs to be segmented for clean URLs and creates path information for TPL and VIEW files as well as creates vars based on extra parameters passed either via URI */
		$this->segment_uri();
				
		/* route the page of the site */
		$this->load_view();
		
		/* Outputs to screen using specified TPL file */
		$this->display();
	}
	
	public function __init_config()
	{
		include_once('config.php');
	}
	
	public function __init_class($path, $classname)
	{
		/* see if $classname exists in class_reg array */
		if (!in_array($classname, $this->class_reg)) 
		{
			/* if not in registry, add it */
			$this->class_reg[] = $classname;
			
			if(file_exists($path)) 
        	{
				/* load the class */
				require_once($path);
			
				/* create the object */
				$this->$classname = new $classname($this);  
			
				$this->log_msg('library loaded: ' . $classname, 'OK');   
			} 
		} else {
			$this->log_msg('library already loaded: ' . $classname . __LINE__ . '/' . __FUNCTION__, 'WARNING');
		}
	}
	
	public function __init_log()
	{
		$path_to_file = $this->DOC_ROOT . '/' . $this->log_path . 'log-' . date ('mdy') . '.txt';
	
		/* if TRUE as specifed in config file proceed, if not skip */
	   	if($this->USE_LOG == TRUE) 
    	{
   			/* Check to see if log file exists */
       		if(!file_exists($path_to_file)) 
        	{
                fopen($path_to_file, "x"); // if doesn't exist, create it 
                $this->log_msg('__init_log() creating log file ' . date ('mdy')      , 'WARNING');             
            } else {
            	$this->log_msg('LOG_STARTED', 'OK');
            }
            
            /* check to see if it is writable */
	        if(is_writable($path_to_file))
	        {
	            $this->log_file_status = 'WRITABLE';
	        }
	        else {
	            chmod($path_to_file, 0777);  // if is not writable, change permissions
	            $this->log_msg('__init_log() changing permissions on log file', 'WARNING');
	        }   
    	}
	}
	
	public function __autoload_libs()
	{  
		#$this->print_array($this->auto_libs);
		
		/* loops through the library array in the config file */
		foreach ($this->auto_libs as $lib_name=>$lib_file) 
        {
        	$path_to_file = $this->library_path . $lib_file;        	
        	if(file_exists($path_to_file))
			{
				$this->__init_class($path_to_file, $lib_name);              
			} else {
				$this->log_msg('__autoload_libs() FAIL ' . $path_to_file, 'WARNING');
			}
        }
	}
	
	private function check_mobile_device()
	{
		/* 	NOTE
			this method will be rewritten to accomodate multiple mobile browsers
			and have decided to halt development on it until future.
		*/
		
		/* Quick check on whether this is an Apple device trying to load the page */
		$Apple = array();
		$Apple['UA'] = $_SERVER['HTTP_USER_AGENT'];
		$Apple['Device'] = false;
		$Apple['Types'] = array('iPhone', 'iPod', 'iPad');
		
		foreach ($Apple['Types'] as $d => $t) {
			$Apple[$t] = (strpos($Apple['UA'], $t) !== false);
			$Apple['Device'] |= $Apple[$t];
		}
		
		/* If Apple Device redirect to apple specific tpl file */
		if($Apple['Device'] == TRUE && preg_match('/m/i', $_SERVER['REQUEST_URI']) != TRUE) 	
		{ header('location:/mobile/' . DEFAULT_VIEW); }
	}

	public function get_theme()
	{
		/* Reassigns the DEFAULT_THEME DEFINE statement to a localized variable for this object */
		/* This may be expanded in the future so it was worth building in now */
		$this->theme = $this->DEFAULT_THEME;
	}
	
	public function load_model($file_name) 
	{
		$path_to_file = $this->model_path . $file_name . '.php';
		if(file_exists($path_to_file))
		{
			$this->__init_class($path_to_file, $file_name);
		} else {
			$this->log_msg('load_model() FAIL ' . $path_to_file, 'WARNING');
		}
	}
	
	public function load_library($file_name) 
	{
		$path_to_file = $this->library_path . $file_name . '.php';
		if(file_exists($path_to_file))
		{
			$this->__init_class($path_to_file, $file_name);		
		} else {
			$this->log_msg('load_library() FAIL ' . $path_to_file, 'WARNING');
		}
	}
	
	public function load_header($file_name='header') 
	{
		$path_to_file = $this->theme_path . $this->theme . '/includes/' . $file_name . '.php';
		if(file_exists($path_to_file))
		{
			include_once($path_to_file);	
		} else {
			$this->log_msg('load_header() FAIL ' . $path_to_file, 'WARNING');
		}
	}
	
	public function load_footer($file_name='footer') 
	{
		$path_to_file = $this->theme_path . $this->theme . '/includes/' . $file_name . '.php';
		if(file_exists($path_to_file))
		{
			include_once($path_to_file);	
		} else {
			$this->log_msg('load_header() FAIL ' . $path_to_file, 'WARNING');
		}
	}
	
	public function load_snip($file_name)
	{	
		$path_to_file = $this->snip_path . $file_name . '.php';
		if(file_exists($path_to_file))
		{
			include_once($path_to_file);
		} else {
			$this->log_msg('load_snip() FAIL ' . $path_to_file, 'WARNING');
		}
	}
	
	public function display()
	{
		/* the final file to include is the TPL, which will wrap it all together */
		$path_to_file = $this->theme_path . $this->theme . '/tpl/' . $this->tpl_key . '.php';
		if(file_exists($path_to_file))
		{
			/* any <?= short tags will be parsed as php */
			$this->log_msg('tpl loaded() ' . $path_to_file, 'OK');
			include_once($path_to_file);
		} else {
			/* Couldn't find the TPL so shoot to an error page */
			$this->log_msg('display() FAIL ' . $this->tpl_key . '/' . __LINE__ . '/' . __FUNCTION__, 'WARNING');
			$this->tpl_key = $this->DEFAULT_TPL;
			include_once($this->theme_path . $this->theme . '/tpl/' . $this->tpl_key . '.php');
		}
	
		$this->log_msg('COMPLETE_PAGE_DISPLAYED', 'OK');
	}
	
	public function load_view()
	{
		print $this->contact_form->view_key_new;
		
		/* content buffering is use to hold the result of the include statement */
		ob_start();
		$path_to_file = $this->views_path . $this->view_key . '.php';
		
		if(file_exists($path_to_file))
		{
			/* any <?= short tags will be parsed as php */
			$this->data['content'] = include_once($path_to_file);
			$this->log_msg('view loaded() ' . $path_to_file, 'OK');
		} else {
			/* Couldn't find the TPL so shoot to an error page */
			$this->log_msg('load_view() FAILED ' . $path_to_file, 'FATAL');
			$this->data['content'] = include_once($this->views_path . '404.php');
		}
		
		/* it is assigned to the content element and then spit out in the TPL file */
		$this->data['content'] = ob_get_contents();
		ob_end_clean();
	}
	
	public function load_meta($loc=NULL)
	{
		/* determine what is being included in $loc */
		if($loc == 'tpl') 
		{
			/* this is a TPL and needs the TPL meta data; assigns path only */
			$path_to_file = $this->meta_path . 'meta_data_' . $this->tpl_key . '.php';
		} else {
			/* this is a VIEW and needs the view meta data; assigns path only */
			$path_to_file = $this->meta_path . $this->view_key . '_meta.php';
		}
		
		/* checks to see if $path_to_file exists and if so includes it; if not it skips it */
		if(file_exists($path_to_file))
		{
			$this->log_msg('meta loaded() ' . $path_to_file, 'OK');
			include_once($path_to_file);
		} else {
			$this->log_msg('load_meta() FAIL ' . $path_to_file, 'WARNING');
		}
	}
	
	public function segment_uri()
	{			
		/* this automagically figures out whether the user is accessing the site via mod_rewrite or query_string */
		/* it also automagically figures out whether the user is requesting a controller or page view */
		
		/* URL_PATH RELATED - MOD_REWRITE */
		if($_GET['mrw'] == 1)
		{
			/* explode the URI into segments separated on slash and then condense array */
			$uri_segment = $_SERVER['REQUEST_URI'];
			$URI_elements = explode('/', $uri_segment);
			$URI_elements = array_filter($URI_elements);
			
			/* check to see if param 1 from above is a controller by checking if the file exists */
			$path_to_file = $this->controller_path . $URI_elements[1] . '.php';
			
			if(file_exists($path_to_file))
			{	
				$this->__init_class($path_to_file, $URI_elements[1]);   

				/* now we need to check to see if method exists and then call it */		
				if(method_exists($URI_elements[1], $URI_elements[2])) 
				{ 
					$this->$URI_elements[1]->$URI_elements[2]();
					
					$this->view_key = $this->$URI_elements[1]->view_key;
					$this->tpl_key = $this->$URI_elements[1]->tpl_key;
				} else { 
					$this->log_msg('segment_uri(FUNCTION_DOES_NOT_EXIST) FAIL ' . $path_to_file . '/' . __LINE__ . '/' . __FUNCTION__, 'WARNING');
				}
			
			/* this is NOT a controller (file does not exist) load as TPL */
			/* but still is mod_rewrite */
			} else {
			
				/* check to see if element count in array is more than 1 otherwise something is wrong */
				if(count($URI_elements) > 1) 
				{					
					$this->tpl_key = $URI_elements[1];
					$this->view_key = $URI_elements[2];
					
					/* process additional parameters after first two sub-paths into variables */
					$i=1;
					foreach ($URI_elements as $key => $value)
					{
						if($i > 2) { ${$value} = $value; $this->$value = $value; } $i++;
						/* ex: /page/about/two/three => page is TPL, about is VIEW */
						/* two becomes $two, three becomes $three &referenced in VIEWS/TPL with $this-> prefix */
					}
				
				/* there were not enough parameters meaning required TPL or VIEW is not there so load DEFAULT_TPL in config and then serve a 404 */	
				} else {
					$this->tpl_key = $this->DEFAULT_TPL;
					$this->view_key = '404';
				}
			}
		
		/* QUERY_STRING METHOD */
		/* deconstruct the query_string similar to above */	
		} else {

			/* checks to make sure the controller trigger/key was not used in URL */
			if(!$_GET[$this->ctrl_key] && !$_GET[$this->method_key] || !$_GET)
			{
				/* Check to see if ?v= is set so that we have a VIEW file if not show a 404 */
				if(!$_GET[$this->view_key])
				{
					if(!$_GET) $this->view_key = $this->DEFAULT_VIEW; else $this->view_key = '404';
				} else {
					$this->view_key = $_GET[$this->view_key];
				}
				
				/* Check to see if ?t is set so that we have a TPL file if not load default TPL */
				if(!$_GET[$this->tpl_key])
				{
					$this->tpl_key = $this->DEFAULT_TPL;
				} else {
					$this->tpl_key = $_GET[$this->tpl_key];
				}	
				
					/* process additional parameters after first two sub-paths into variables */
					foreach ($_GET as $key => $value)
					{
						if($key != $this->tpl_key || $key != $this->tpl_view) { ${$value} = $value; $this->$value = $value; }
						/* ex: ?t=page&v=about&two=two&three=three => ?t is TPL, ?v is VIEW (OR WHAT YOU HAVE ASSIGNED THEM) */
						/* two becomes $two, three becomes $three &referenced in VIEWS/TPL with $this-> prefix */
					}
					
			} else {
				/* controller trigger/key was used and checking if the file exists */
				$path_to_file = $this->controller_path . $_GET[$this->ctrl_key] . '.php';

				$this->__init_class($path_to_file, $_GET[$this->ctrl_key]);   

				/* now we need to check to see if method exists and then call it */		
				if(method_exists($_GET[$this->ctrl_key], $_GET[$this->method_key])) 
				{ 
					$this->contact_form->$_GET[$this->method_key]();
					$this->view_key = $this->$_GET[$this->ctrl_key]->view_key;
					$this->tpl_key = $this->$_GET[$this->ctrl_key]->tpl_key;
				} else { 
					$this->log_msg('segment_uri(FUNCTION_DOES_NOT_EXIST) FAIL ' . $path_to_file . '/' . __LINE__ . '/' . __FUNCTION__, 'WARNING');

				}	
			}	
		}
	}
	
	public function log_msg($msg, $level)
	{				
	   	$path_to_file = $this->DOC_ROOT . '/' . $this->log_path . 'log-' . date ('mdy') . '.txt';
		
		/* format the log string that is written to file */
       	$msg_str	 =	strtolower($level) . ' | ';
       	$msg_str	.= 	date("Y-m-d H:i:s") . ' | ';
       	$msg_str	.=	$_SERVER["REMOTE_ADDR"] . ' | ';
       	$msg_str	.=	$msg;
       	$msg_str 	.= "\n";
       	
       	/* Checks to see if the log should be written as specified in config file */
		if(USE_LOG == TRUE)
		{
			$fp = fopen($path_to_file, "a");
			flock($fp, LOCK_EX);	
			fwrite($fp, $msg_str);
			flock($fp, LOCK_UN);
			fclose($fp);
		}
	}

	public function print_array($arr, $style='pr')
	{
		switch($style)
		{
			case "pr":
			$style = 'print_r';
			break;
			
			case "vd":
			$style = 'var_dump';
			break;
		}
		
		print "<div style='width: 500px; background-color: #AAA; padding: 40px;'>";
		print "<pre>";
		$style($arr);
		print "</pre>";
		print "<p style='margin-top: 20px'>print_array().done</p>";
		print "</div>";
	}
}

/* End of file*/
/* Location: ./controllers/pasteboard_c.php */